﻿using KingsSharp.Common.Logging;
using KingsSharp.Core.Logging;
using log4net.Core;
using System;
using System.Collections.Generic;
using ILogger = log4net.Core.ILogger;

namespace CRM.Admin
{
    public class Log4NetLog : LogBase
    {
        private static readonly Type DeclaringType = typeof(Log4NetLog);
        private readonly ILogger _logger;

        internal Log4NetLog(ILoggerWrapper wrapper)
        {
            _logger = wrapper.Logger;
        }

        #region Overrides of LogBase

        /// <summary>
        /// 获取 是否允许<see cref="LogLevel.Trace"/>级别的日志
        /// </summary>
        public override bool IsTraceEnabled { get { return _logger.IsEnabledFor(Level.Trace); } }

        /// <summary>
        /// 获取 是否允许<see cref="LogLevel.Debug"/>级别的日志
        /// </summary>
        public override bool IsDebugEnabled { get { return _logger.IsEnabledFor(Level.Debug); } }

        /// <summary>
        /// 获取 是否允许<see cref="LogLevel.Info"/>级别的日志
        /// </summary>
        public override bool IsInfoEnabled { get { return _logger.IsEnabledFor(Level.Info); } }

        /// <summary>
        /// 获取 是否允许<see cref="LogLevel.Warn"/>级别的日志
        /// </summary>
        public override bool IsWarnEnabled { get { return _logger.IsEnabledFor(Level.Warn); } }

        /// <summary>
        /// 获取 是否允许<see cref="LogLevel.Error"/>级别的日志
        /// </summary>
        public override bool IsErrorEnabled { get { return _logger.IsEnabledFor(Level.Error); } }

        /// <summary>
        /// 获取 是否允许<see cref="LogLevel.Fatal"/>级别的日志
        /// </summary>
        public override bool IsFatalEnabled { get { return _logger.IsEnabledFor(Level.Fatal); } }


        /// <summary>
        /// 获取日志输出处理委托实例
        /// </summary>
        /// <param name="level">日志输出级别</param>
        /// <param name="message">日志消息</param>
        /// <param name="exception">日志异常</param>
        protected override void WriteInternal(LogLevel level, object message, Exception exception)
        {
            Level level1 = GetLevel(level);
            if (level == LogLevel.Info && message is IEnumerable<OperatingLog>)
            {

                IEnumerable<OperatingLog> logs = message as IEnumerable<OperatingLog>;
                string logout = "";
                foreach(var log in logs)
                {
                    logout += "操作Model：" + log.EntityName + "，操作类型：" + log.OperateType;
                    logout += "，操作人：" + log.Operator.Name + "，操作IP：" + log.Operator.Ip + "\r\n";
                    logout += "实体主键ID：" + log.Id + "\r\n";
                    logout += "-----------------操作明细-----------------\r\n";
                    foreach (var logitem in log.LogItems)
                    {

                        if (log.OperateType.ToString().ToLower() == "insert")
                        {
                            logout += "字段：" + logitem.Field + " -> 值：" + logitem.NewValue + "\r\n";
                        }
                        else
                        {
                            logout += "字段：" + logitem.Field + ",原始值：" + logitem.OriginalValue + " -> 新值：" + logitem.NewValue + "\r\n";
                        }
                    }
                }
                if (logout!="")
                { 
                    _logger.Log(DeclaringType, level1, logout, exception); 
                }
                return;
            }
            _logger.Log(DeclaringType, level1, message, exception);
        }
        public override void Debug<T>(T message)
        {
            base.Debug<T>(message);
        }
        #endregion

        private static Level GetLevel(LogLevel level)
        {
            switch (level)
            {
                case LogLevel.All:
                    return Level.All;
                case LogLevel.Trace:
                    return Level.Trace;
                case LogLevel.Debug:
                    return Level.Debug;
                case LogLevel.Info:
                    return Level.Info;
                case LogLevel.Warn:
                    return Level.Warn;
                case LogLevel.Error:
                    return Level.Error;
                case LogLevel.Fatal:
                    return Level.Fatal;
                case LogLevel.Off:
                    return Level.Off;
                default:
                    return Level.Off;
            }
        }
    }
}